﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Glucometer.UserInterface
{
    public partial class GlucometerDeviceHardware : Form, IHarware
    {

        public event d_Interrupt RaiseInterrupt;

        public GlucometerDeviceHardware()
        {
            InitializeComponent();

            cmpModeDisplay.BackColor = Color.FromArgb(180, 198, 184);

            blkDtControl.BackColor = Color.FromArgb(180, 198, 184);

            lblTestUnit.BackColor = Color.FromArgb(180, 198, 184);

            blinkingBattery1.Visible = false;

            txtErrorDescription.Text = Glucometer.ErrorCodeResolver.GetDescription();
        }

        public void DisplayResult(int result, TestUnit unit)
        {
            lblResult.Invoke((MethodInvoker)(() => lblResult.Text = result.ToString() + unit.ToString()));
        }
        
        public void SetDeviceMode(OperationMode mode)
        {
            cmpModeDisplay.Invoke((MethodInvoker)(() => cmpModeDisplay.StopBlinkingAndHideAll()));

            if (mode == OperationMode.TESTING)
            {
                cmpModeDisplay.Invoke((MethodInvoker)(() => cmpModeDisplay.ShowComponent(DisplayComponent.DEVICE_MODE_TESTING)));
                lblTestUnit.Invoke((MethodInvoker)(() => lblTestUnit.Visible = true));
            }
            else if (mode == OperationMode.BROWSING)
            {
                cmpModeDisplay.Invoke((MethodInvoker)(() => cmpModeDisplay.ShowComponent(DisplayComponent.DEVICE_MODE_BROWSING)));
            }
            else if (mode == OperationMode.UPLOADING)
            {
                cmpModeDisplay.Invoke((MethodInvoker)(() => cmpModeDisplay.ShowComponent(DisplayComponent.DEVICE_MODE_UPLOADING)));
            }
            else if (mode == OperationMode.SETUP)
            {
                lblTestUnit.Invoke((MethodInvoker)(() => lblTestUnit.Visible = true));
                blkDtControl.Invoke((MethodInvoker)(() => blkDtControl.Visible = true));
                blkDtControl.Invoke((MethodInvoker)(() => blkDtControl.stopBlinking()));
            }

            if (mode == OperationMode.NONE)
            {
                lblTestUnit.Invoke((MethodInvoker)(() => lblTestUnit.Visible = false));
                lblTestUnit.Invoke((MethodInvoker)(() => lblTestUnit.stopBlinking()));
                blkDtControl.Invoke((MethodInvoker)(() => blkDtControl.Visible = false));
                blkDtControl.Invoke((MethodInvoker)(() => blkDtControl.stopBlinking()));
                lblResult.Invoke((MethodInvoker)(() => lblResult.Text = ""));
                progressBar.Invoke((MethodInvoker)(() => progressBar.Visible = false)); 
            }
        }

        public void BlinkMode(OperationMode mode)
        {
            SetDeviceMode(mode);
            if (mode == OperationMode.TESTING)            
                cmpModeDisplay.Invoke((MethodInvoker)(() =>cmpModeDisplay.BlinkComponent(DisplayComponent.DEVICE_MODE_TESTING)));
            else if (mode == OperationMode.BROWSING)
                cmpModeDisplay.Invoke((MethodInvoker)(() =>cmpModeDisplay.BlinkComponent(DisplayComponent.DEVICE_MODE_BROWSING)));
            else if (mode == OperationMode.UPLOADING)
                cmpModeDisplay.Invoke((MethodInvoker)(() =>cmpModeDisplay.BlinkComponent(DisplayComponent.DEVICE_MODE_UPLOADING)));
        }


        //NOT USED
        public void DecreaseBatteryLevel()
        {
            throw new NotImplementedException();
        }

        //NOT USED
        public void IncreaseBatteryLevel()
        {
            throw new NotImplementedException();
        }

        //NOT IMPORTANT
        public void ShowDisplay(string p)
        {
            //lblResult.Invoke((MethodInvoker)(() => lblResult.Text = p));
        }

        //NOT USED
        public void ShowMode(string mode)
        {
            //lblMode.Invoke((MethodInvoker)(() => lblMode.Text = mode));
        }

        public void ShowProgress(int progress)
        {
            if (progress == -1)
            {
                progressBar.Invoke((MethodInvoker)(() => progressBar.Visible = false));
                return;
            }

            progressBar.Invoke((MethodInvoker)(() => progressBar.Visible = true));            

            progressBar.Invoke((MethodInvoker)(() => progressBar.Value = progress));
        }

        public void showCurrentRecord(string str)
        {
            //BrowsingScreen.Invoke((MethodInvoker)(() => BrowsingScreen.Text = str));
            lblResult.Invoke((MethodInvoker)(() => lblResult.Text = str));

        }

        public void BlinkSetupPosition(SetupModePosition pos)
        {
            switch (pos)
            {
                case SetupModePosition.FIRST_DIGIT_OF_YEAR:
                    lblTestUnit.stopBlinking();
                    blkDtControl.BlinkPosition(0);
                    break;
                case SetupModePosition.SECOND_DIGIT_OF_YEAR:
                    blkDtControl.BlinkPosition(1);
                    break;
                case SetupModePosition.FIRST_DIGIT_OF_MONTH:
                    blkDtControl.BlinkPosition(2);
                    break;
                case SetupModePosition.SECOND_DIGIT_OF_MONTH:
                    blkDtControl.BlinkPosition(3);
                    break;
                case SetupModePosition.FIRST_DIGIT_OF_DAY:
                    blkDtControl.BlinkPosition(4);
                    break;
                case SetupModePosition.SECOND_DIGIT_OF_DAY:
                    blkDtControl.BlinkPosition(5);
                    break;
                case SetupModePosition.FIRST_DIGIT_OF_HOUR:
                    blkDtControl.BlinkPosition(6);
                    break;
                case SetupModePosition.SECOND_DIGIT_OF_HOUR:
                    blkDtControl.BlinkPosition(7);
                    break;
                case SetupModePosition.FIRST_DIGIT_OF_MINUTE:
                    blkDtControl.BlinkPosition(8);
                    break;
                case SetupModePosition.SECOND_DIGIT_OF_MINUTE:
                    blkDtControl.BlinkPosition(9);
                    break;
                case SetupModePosition.TEST_UNIT:
                    lblTestUnit.startBlinking(2);
                    break;
            }
        }

        public void DisplayErrorCode(int code)
        {
            lblResult.Invoke((MethodInvoker)(() => lblResult.Text = code.ToString()));
            cmpModeDisplay.Invoke((MethodInvoker)(() => cmpModeDisplay.ShowComponent(DisplayComponent.DEVICE_MODE_ERROR)));
        }

        public bool getStatus(HardwareStatus status)
        {
            if (status == HardwareStatus.IS_VALID_TEST_STRIP)
                return chkStrip.Checked;
            return true; 
        }

        
        public void BlinkComponent(DisplayComponent component)
        {
            if (component == DisplayComponent.BATTERY)
            {
                blkDtControl.Invoke((MethodInvoker)(() => blinkingBattery1.startBlinking(1)));
            }
        }

        public void UpdateSetupPositionValue(SetupModePosition pos, string c)
        {
            if (pos == SetupModePosition.TEST_UNIT)
                lblTestUnit.Invoke((MethodInvoker)(() => lblTestUnit.Text = c.ToString()));
            else
                blkDtControl.Invoke((MethodInvoker)(() => blkDtControl.setCurrentPositionDisplay(c)));
        }

        public void updateDateTime(DateTime dt)
        {
            blkDtControl.Invoke((MethodInvoker)(() => blkDtControl.setDateTime(dt)));
            blkDtControl.Invoke((MethodInvoker)(() => blkDtControl.Visible = true));
        }

        //NOT USED
        public void showError(ErrorCode _lastError, string _lastErrorMessage)
        {
            //lblErrorCode.Invoke((MethodInvoker)(() => lblErrorCode.Text = _lastError.ToString()));
            //lblError.Invoke((MethodInvoker)(() => lblError.Text = _lastErrorMessage.ToString()));
        }

        public void ShowBatteryLevel(int level)
        {
            if(level == 0 || level >1)
                blkDtControl.Invoke((MethodInvoker)(() => blinkingBattery1.stopBlinking()));
            blinkingBattery1.Invoke((MethodInvoker)(() => blinkingBattery1.Visible = true));
            blinkingBattery1.Invoke((MethodInvoker)(() => blinkingBattery1.BatteryLevel = level));

            //picBoxBattery.Invoke((MethodInvoker)(() => picBoxBattery.Visible = true));

            //if (level == 0)
            //    picBoxBattery.Image = Properties.Resources.level_01;
            //else if (level == 1)
            //    picBoxBattery.Image = Properties.Resources.level_11;
            //else if (level == 2)
            //    picBoxBattery.Image = Properties.Resources.level_21;
            //else if (level == 3)
            //    picBoxBattery.Image = Properties.Resources.level_31;
            //else if (level == 4)
            //    picBoxBattery.Image = Properties.Resources.level_41;
            //else
            //    picBoxBattery.Invoke((MethodInvoker)(() => picBoxBattery.Visible = false));

            //picBoxBattery.Invoke((MethodInvoker)(() => picBoxBattery.Invalidate()));
        }

        public void ShowAcSymbol(bool visible)
        {
            picBoxAcSymbol.Invoke((MethodInvoker)(() => picBoxAcSymbol.Visible = visible));
        }

        public void ShowMode(DisplayComponent displayComponent)
        { }

        private void button1_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Space && RaiseInterrupt != null)
                RaiseInterrupt(HardwareInterrupt.BUTTON_UP);
        }

        private void button1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Space && RaiseInterrupt != null)
                RaiseInterrupt(HardwareInterrupt.BUTTON_DOWN);
        }

        private void button1_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Left && RaiseInterrupt != null)
                RaiseInterrupt(HardwareInterrupt.BUTTON_UP);
        }

        private void button1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Left && RaiseInterrupt != null)
                RaiseInterrupt(HardwareInterrupt.BUTTON_DOWN);
        }

        private void chkUSB_CheckedChanged(object sender, EventArgs e)
        {
            if (RaiseInterrupt != null)
            {
                if (chkUSB.Checked)
                    RaiseInterrupt(HardwareInterrupt.USB_INSERTED);
                else
                    RaiseInterrupt(HardwareInterrupt.USB_REMOVED);
            }
        }

        private void chkAcPlugged_CheckedChanged(object sender, EventArgs e)
        {
            if (RaiseInterrupt != null)
            {
                if(chkAcPlugged.Checked)
                    RaiseInterrupt(HardwareInterrupt.AC_PLUGGED_IN);
                else
                    RaiseInterrupt(HardwareInterrupt.AC_PLUGGED_OUT);
            }
        }

        private void chkStrip_CheckedChanged(object sender, EventArgs e)
        {
            if (!chkStrip.Enabled)
            {
                chkStrip.Checked = !chkInvalidStrip.Checked;
                return;
            }
            else if(chkStrip.Checked)
            {
                chkInvalidStrip.Enabled = false;
            }
            else
            {
                chkInvalidStrip.Enabled = true;
            }

            

            if (RaiseInterrupt != null)
            {
                if (chkStrip.Checked)
                {
                    RaiseInterrupt(HardwareInterrupt.STRIP_INSERTED);
                }
                else
                    RaiseInterrupt(HardwareInterrupt.STRIP_REMOVED);
            }
        }

        private void btnSufficientBlood_Click(object sender, EventArgs e)
        {
            if(RaiseInterrupt != null)
                RaiseInterrupt(HardwareInterrupt.SUFFICIENT_BLOOD);
        }

        private void btnInSufficientBlood_Click(object sender, EventArgs e)
        {
            if (RaiseInterrupt != null)
                RaiseInterrupt(HardwareInterrupt.INSUFFICIENT_BLOOD);
        }

        private void btnResultReady_Click(object sender, EventArgs e)
        {
            if(RaiseInterrupt != null)
                RaiseInterrupt(HardwareInterrupt.RESULT_READY);
        }

        private void chkInvalidStrip_CheckedChanged(object sender, EventArgs e)
        {
            if (!chkInvalidStrip.Enabled)
            {
                chkInvalidStrip.Checked = !chkStrip.Checked;
                return;
            }
            else if (chkInvalidStrip.Checked)
            {
                chkStrip.Enabled = false;
            }
            else
            {
                chkStrip.Enabled = true;
            }

            if (RaiseInterrupt != null)
            {
                if (chkInvalidStrip.Checked)
                {
                    RaiseInterrupt(HardwareInterrupt.STRIP_INSERTED);
                }
                else
                    RaiseInterrupt(HardwareInterrupt.STRIP_REMOVED);
            }
        }

        //public void PowerOn()
        //{
        //    picBoxBattery.Invoke((MethodInvoker)(() => picBoxBattery.Visible = true));
        //}

        //public void PowerOff()
        //{
        //    picBoxBattery.Invoke((MethodInvoker)(() => picBoxBattery.Visible = false));
        //    SetDeviceMode(OperationMode.NONE);
        //}
    }
}
